package homework015;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;

public class Server {

    private static Properties properties = new Properties();

    // 从文件读取映射关系
    static {
        try {
            // 读取配置文件
            FileReader fr = new FileReader("C:\\space-class\\27\\javase_homework\\src\\day15\\route\\conf\\router.properties");
            properties.load(fr);
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        // 作为服务端，第一步就是开启ServerSocket
        // 步骤1：new ServerSocket
        ServerSocket ss = new ServerSocket(8888);

        // 步骤2：等待客户端连接
        Socket accept = ss.accept();

        // 步骤3：创建输入流，读取数据
        InputStream is = accept.getInputStream();
        int b;
        String path = "";
        while ((b = is.read()) != -1) {
            // 步骤4：没读到一个字节，就转成字符，并最终拼装成字符串
            path += (char) b;
        }

        // 步骤5：根据接收到的字符串，判断要执行的类方法
        String result = getMapping(path);
        System.out.println(result);

        // 步骤6：关闭流和socket
        is.close();
        ss.close();
    }

    private static String getMapping(String path) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {

        // 步骤1： 获取字节流对象
        // Class<?> aClass = Class.forName()
        // 上面这句其实是根据传进来的path获取对应的类名
        // 比如传进来的是 /user
        // 那么 properties.getProperty("/path") 的结果就是 com.itheima.UserServlet
        // 不知道为什么的，可以复习一下双列集合怎么操作的
        Class<?> aClass = Class.forName(properties.getProperty(path));

        // 步骤2：获取成员方法数组
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if ("run".equals(method.getName())) {

                // 步骤3：使用invoke执行成员方法
                // 因为这里执行的run方法没有入参，所以只需要传一个参数就行
                return (String) method.invoke(new Object());
            }
        }

        return "";
    }
}
